package 线程andJUC;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class main {
    /*
    线程是操作系统可运行的最小单位，他被包含在进程中，是进程中的实际运作单位
    进程是程序的基本执行实体
    例如：360安全卫士这个本身是个进程，而其内部的木马查杀，电脑清理，系统修复被称为线程
     */
    /*
    并发：在同一时间段，有多个指令在单个cpu上交替执行
    并行：在同一时刻，有多个指令在多个cpu上同时执行
    并发和并行有可能同时发生
     */

    /*
    多线程的第一种启动方式
    1.自己定义一个类继承Thread
    2.重写run方法
    3.创建子类的对象，并启动线程
   */
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //       创建线程对象
        System.out.println("第一种启动方式");
        MyThread M10 = new MyThread();
        MyThread M20 = new MyThread();
        M10.setName("线程一");
        M20.setName("线程二");
//        M10.start();
//        M20.start();


        /*
        多线程的第二种启动方式
        1.自己定义一个类实现Runnable接口
        2.重写run方法
        3.创建自己类的对象，并启动线程
        4.创建一个Thread类的对象，并开启线程
        */
        System.out.println("第二种启动方式");
//        创建MyThread1对象
        MyThread1 M21=new MyThread1();
//        创建线程对象
        Thread t1=new Thread(M21);
        Thread t2=new Thread(M21);
//        给线程设置名字
        t1.setName("线程一");
        t2.setName("线程二");
//        开启线程
//        t1.start();
//        t2.start();


        /*
        多线程的第三种启动方式
        特点：可以获得多线程的运行结果
        1.创建一个类实现Callable接口
        2.重写call(有返回值，表示多线程运行的结果)
        3.创建类的对象（表示多线程要执行的任务）
        4.创建FutureTask的对象（作用管理多线程运行的结果）
        5.创还能Thread类的对象，并启动（表示线程）
        */
        //创建类的对象（表示多线程要执行的任务）
        MyThread2 m31 =new MyThread2();
//        创建FutureTask的对象（作用管理多线程运行的结果）
        FutureTask<Integer> ft=new FutureTask<>(m31);
//        创建线程
        Thread t3=new Thread(ft);
//        启动线程
        t1.start();
//        获得多线程运行的结果
        Integer result=ft.get();
        System.out.println(result);


        //        开启线程
        //        start来启动线程：将线程加入到线程队列中，只有队列中的线程才有资格向cpu申请可能执行
        //        run


        /*
        Thread和Runnable的区别
        1.集成Thread后就不再继承其他的类
        2.集成Thread不利于扩展，创建线程和进程要执行任务的耦合
        Runnable优势
        1.扩展性好，在实现接口类的同时，还可以继承其他类
        2.耦合度低，Runnable
         */

    }
}
class MyThread extends Thread {

    @Override
    public void run() {
//            书写线程要执行的代码
        for (int i = 0; i < 10; i++) {
            System.out.println(getName()+":helloworld");
        }
    }
}
class MyThread1 implements Runnable{

    @Override
    public void run() {
        //            书写线程要执行的代码
        for (int i = 0; i < 10; i++) {
//            获取当前线程的对象
            Thread t=Thread.currentThread();//t1,t2

            System.out.println(t.getName()+":helloworld");
        }
    }
}
class MyThread2 implements Callable<Integer>{

    @Override
    public Integer call() throws Exception {
//        求1~100之间的和
        int sum=0;
        for (int i = 0; i < 101; i++) {
            sum=sum+1;
        }
        return sum;
    }
}



